/**
 * 路由配置文件
 * 设置应用的路由结构，包括公共路由和受保护路由
 * 实现路由级别的权限控制
 */
import React from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';   // React Router v6路由组件，用于定义路由结构和导航
import ProtectedRoute from '../components/permission/ProtectedRoute';     // 导入路由权限保护组件，用于控制页面访问权限
import ErrorBoundary from '../components/ErrorBoundary';       // 导入错误边界组件，用于捕获路由渲染时的错误
import { publicRoutes, protectedRoutes, RouteConfig } from './routes'; // 导入路由配置数据：公共路由、受保护路由及路由类型定义

/**
 * 渲染公共路由函数
 * 处理不需要权限验证的路由，如登录页面、新闻列表等公开页面
 * 支持递归渲染嵌套路由结构
 * 
 * @param {RouteConfig[]} routes - 公共路由配置数组
 * @returns {JSX.Element[]} 渲染后的Route元素数组
 */
function renderPublicRoutes(routes: RouteConfig[]) {
  return routes.map((route) => {
    // 根据配置创建路由组件实例，使用React.createElement动态创建React组件
    // 如果route.element是React组件类型，则创建组件实例；否则返回null
    const RouteElement = route.element ? 
      React.createElement(route.element as React.ComponentType) : null;

    // 处理包含子路由的情况，需要创建嵌套路由结构
    if (route.children && route.children.length > 0) {
      return (
        // 为当前路由创建Route元素，使用path属性设置路径，element属性设置要渲染的组件
        <Route key={route.path} path={route.path} element={RouteElement}>
          {/* 如果配置了重定向属性，添加索引路由进行重定向 */}
          {/* 索引路由会在访问父路由时自动重定向到指定子路由 */}
          {route.redirect && <Route index element={<Navigate to={route.redirect} replace />} />}
          
          {/* 递归调用自身，渲染所有子路由 */}
          {/* 这样可以处理任意层级的嵌套路由结构 */}
          {renderPublicRoutes(route.children)}
        </Route>
      );
    }
    
    // 无子路由的情况，直接返回单个Route元素
    return (
      <Route
        key={route.path}  // 使用路径作为唯一键值
        path={route.path} // 设置路由路径
        element={RouteElement} // 设置要渲染的组件
      />
    );
  });
}

/**
 * 渲染受保护路由函数
 * 处理需要权限验证的路由，如管理页面、用户后台等需要登录才能访问的页面
 * 为需要权限的路由添加ProtectedRoute包装，实现权限控制
 * 
 * @param {RouteConfig[]} routes - 受保护路由配置数组
 * @returns {JSX.Element[]} 渲染后的Route元素数组
 */
function renderProtectedRoutes(routes: RouteConfig[]) {
  return routes.map((route) => {
    // 根据配置创建路由组件实例
    let RouteElement = route.element ? 
      React.createElement(route.element as React.ComponentType) : null;

    // 如果路由需要权限验证且不是容器路由（没有子路由），用ProtectedRoute组件包装
    // auth属性表示需要身份验证，permission属性指定所需权限
    if (route.auth && !route.children) {
      // 将路由元素包装在ProtectedRoute组件中，传入所需权限
      // ProtectedRoute会检查用户是否有权限访问，无权限则重定向
      RouteElement = <ProtectedRoute requiredPermission={route.permission}>{RouteElement}</ProtectedRoute>;
    }

    // 处理包含子路由的情况，需要创建嵌套路由结构
    if (route.children && route.children.length > 0) {
      return (
        // 为当前路由创建Route元素
        <Route key={route.path} path={route.path} element={RouteElement}>
          {/* 如果配置了重定向属性，添加索引路由进行重定向 */}
          {/* 例如：访问/home会自动重定向到/home/dashboard */}
          {route.redirect && <Route index element={<Navigate to={route.redirect} replace />} />}
          
          {/* 递归渲染子路由，保持权限控制的继承性 */}
          {/* 父路由的权限控制会影响所有子路由 */}
          {renderProtectedRoutes(route.children)}
        </Route>
      );
    }
    
    // 无子路由的情况，直接返回单个Route元素
    return (
      <Route
        key={route.path}  // 使用路径作为唯一键值
        path={route.path} // 设置路由路径
        element={RouteElement} // 设置要渲染的组件（可能已被ProtectedRoute包装）
      />
    );
  });
}

/**
 * 应用路由组件
 * 整合公共路由和受保护路由，设置默认重定向和未匹配路由处理
 * 
 * 提供应用的完整路由结构：
 * 1. 根路径重定向到首页或登录页（取决于认证状态）
 * 2. 渲染所有公共路由（不需要权限验证）
 * 3. 渲染所有受保护路由（需要权限验证）
 * 4. 未匹配路由重定向到首页或登录页
 * 
 * @returns {JSX.Element} 完整的路由结构组件
 */
const AppRouter: React.FC = () => {
  // 获取认证状态
  const isAuthenticated = !!localStorage.getItem('token');
  
  // 记录路由初始化
  console.log('AppRouter初始化，认证状态:', isAuthenticated);

  return (
    // 使用ErrorBoundary包裹整个路由结构，捕获路由渲染时可能出现的错误
    <ErrorBoundary>
      {/* Routes组件定义路由规则集合，仅匹配一个路由进行渲染 */}
      <Routes>
        {/* 根路径重定向到首页或登录页（取决于认证状态） */}
        <Route index path="/" element={
          isAuthenticated ? <Navigate to="/home" replace /> : <Navigate to="/login" replace />
        } />
        
        {/* 渲染所有公共路由，如登录页、公开内容页等 */}
        {renderPublicRoutes(publicRoutes)}
        
        {/* 渲染所有受保护路由，这些路由需要权限验证 */}
        {/* 包括管理后台、个人中心等需要登录才能访问的页面 */}
        {renderProtectedRoutes(protectedRoutes)}
        
        {/* 未匹配路由兜底处理，重定向到首页或登录页 */}
        <Route path="*" element={
          isAuthenticated ? <Navigate to="/home" replace /> : <Navigate to="/login" replace />
        } />
      </Routes>
    </ErrorBoundary>
  );
};

// 导出路由组件作为默认导出
export default AppRouter;